package com.jdpc.weparty.controller

import com.jdpc.weparty.controller.vo.*
import com.jdpc.weparty.entity.Activity
import com.jdpc.weparty.entity.User
import com.jdpc.weparty.service.activity.ActivityService
import com.jdpc.weparty.service.activity.signup.SignUpActivityService
import com.jdpc.weparty.service.pic.PictureService
import com.jdpc.weparty.service.rsa.RsaService
import com.jdpc.weparty.service.user.UserInfo
import com.jdpc.weparty.service.user.UserService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageImpl
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import javax.servlet.http.HttpServletResponse


@RestController
class UserController {
    @Autowired
    lateinit var userService: UserService

    @Autowired
    lateinit var signUpActivityService: SignUpActivityService

    @Autowired
    lateinit var activityService: ActivityService

    @Autowired
    lateinit var pictureService: PictureService

    @Autowired
    lateinit var rsaService: RsaService

    @GetMapping("/avatar/{picName}", produces = [MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE])
    fun getAvatar(response: HttpServletResponse, @PathVariable("picName") picName: String) {
        pictureService.responseAvatar(response, picName)

    }

    //注册
    @PostMapping("/users")
    fun register(@RequestBody info: UserVo): ResponseEntity<*> {
        if (info.password.trim() == "" || info.phoneNumber.trim() == "") {
            return ResponseEntity.badRequest().body(JsonBody(-2, "必须填写手机号密码", Any()))

        }
        val result = userService.register(UserInfo(
                info.phoneNumber,
                info.userName,
                info.gender,
                info.age,
                info.userNumber,
                info.avatar
        ), rsaService.decoder(info.password))//用户id
        if (result == null) {
            return ResponseEntity.ok(JsonBody(-1, "该手机号已被注册", Any()))
        }
        result.password = ""
        return ResponseEntity.ok(JsonBody(0, "成功", result))
    }

    //按照id请求用户信息
    @GetMapping("/users/{id}")
    fun getUser(@PathVariable("id") uId: Int): ResponseEntity<*> {
        userService.getUser(uId)?.let {
            return ResponseEntity.ok(JsonBody(0, "成功", UserVo().apply {
                setInfo(it)
            }))
        } ?: return ResponseEntity.badRequest().body(JsonBody(-1, "用户(uId=$uId) 不存在", null))
    }

    //修改用户信息
    @PutMapping("/users/{id}")
    fun changeUser(@PathVariable("id") uId: Int, @RequestBody info: UserVo): ResponseEntity<*> {
        val result = userService.changeInfo(uId, UserInfo(
                info.phoneNumber,
                info.userName,
                info.gender,
                info.age,
                info.userNumber,
                info.avatar
        ))
        return if (result) {
            ResponseEntity.ok(JsonBody(0, "成功", Any()))
        } else {
            ResponseEntity.badRequest().body(JsonBody(-1, "修改失败,用户(uId=$uId) 不存在", Any()))
        }
    }

    //获取id用户参加的所有活动
    @GetMapping("/users/{id}/joined")
    fun getJoinedActivities(@PathVariable("id") id: Int, @RequestParam("state", required = false, defaultValue = "default") state: String, @RequestParam("page", required = false) page: Int?, @RequestParam("size", required = false) size: Int?): ResponseEntity<*> {
        if (page != null && size != null) {
            val pageable = PageRequest.of(page, size)

            var list = when (state) {
//            "default" -> {
//                getSignUpActivities(id, true).apply {
//                    addAll(getSignUpActivities(id, null))
//                    addAll(getSignUpActivities(id, false))
//                }
//            }
                "passing" -> {
                    getSignUpActivities(id, null, pageable)
                }
                "passed" -> {
                    getSignUpActivities(id, true, pageable)


                }
                "deny" -> {
                    getSignUpActivities(id, false, pageable)

                }
                else -> {

                    getSignUpActivities(id, pageable)
                }
            }
            return ResponseEntity.ok(JsonBody(0, "成功", list))
        } else {
            var list = when (state) {
//            "default" -> {
//                getSignUpActivities(id, true).apply {
//                    addAll(getSignUpActivities(id, null))
//                    addAll(getSignUpActivities(id, false))
//                }
//            }
                "passing" -> {
                    getSignUpActivities(id, null)
                }
                "passed" -> {
                    getSignUpActivities(id, true)


                }
                "deny" -> {
                    getSignUpActivities(id, false)

                }
                else -> {
                    getSignUpActivities(id, true).apply {
                        addAll(getSignUpActivities(id, null))
                        addAll(getSignUpActivities(id, false))
                    }
                }
            }
            return ResponseEntity.ok(JsonBody(0, "成功", list))

        }
    }

    private fun getSignUpActivities(userId: Int, pageable: Pageable): Page<Activity4JoinerVo> {
        val activityPage = signUpActivityService.getActivityForm(userId, pageable)
        return PageImpl<Activity4JoinerVo>(activityPage.content.map { signUp ->
            val activity = activityService.findActivity(signUp.activityId) as Activity
            val num = signUpActivityService.getUserForm(activity.id, true).size
            return@map Activity4JoinerVo(ActivityInfoVo(activity, num), signUp.passed)
        }, PageRequest.of(activityPage.number, activityPage.size), activityPage.totalElements)
    }

    private fun getSignUpActivities(userId: Int, passed: Boolean?, pageable: Pageable): Page<Activity4JoinerVo> {
        val activityPage = signUpActivityService.getActivityForm(userId, passed, pageable)
        return PageImpl<Activity4JoinerVo>(activityPage.content.map {
            val num = signUpActivityService.getUserForm(it.id, true).size
            Activity4JoinerVo(ActivityInfoVo(it, num), passed)
        }, PageRequest.of(activityPage.number, activityPage.size), activityPage.totalElements)
    }

    //活动参与者查找待申请的活动
    private fun getSignUpActivities(userId: Int, passed: Boolean?): MutableList<Activity4JoinerVo> = signUpActivityService.getActivityForm(userId, passed).map {
        val num = signUpActivityService.getUserForm(it.id, true).size
        Activity4JoinerVo(ActivityInfoVo(it, num), passed)
    }.toMutableList()

    //获取id用户发布过的活动
    @GetMapping("/users/{id}/published")
    fun getPublishedActivities(@PathVariable("id") id: Int, @RequestParam("state", required = false, defaultValue = "default") state: String, @RequestParam("page", required = false) page: Int?, @RequestParam("size", required = false) size: Int?): ResponseEntity<*> {
        if (page != null && size != null) {
            val user = userService.getUser(id)
            val pageable = PageRequest.of(page, size)
            val list = when (state) {
                "checking" -> {
                    user?.let {
                        getActivitiesPublisher(it, null, pageable)
                    }
                }
                "checked" -> {
                    user?.let {
                        getActivitiesPublisher(it, true, pageable)
                    }
                }
                "deny" -> {
                    user?.let {
                        getActivitiesPublisher(it, false, pageable)
                    }
                }
                else -> {
                    user?.let {
                        getActivitiesPublisher(it, pageable)
                    }
                }
            } ?: listOf<Activity4PublisherVo>()
            return ResponseEntity.ok(JsonBody(0, "成功", list))
        } else {
            val user = userService.getUser(id)
            val list = when (state) {
                "checking" -> {
                    user?.let {
                        getActivitiesPublisher(it, null)
                    }
                }
                "checked" -> {
                    user?.let {
                        getActivitiesPublisher(it, true)
                    }
                }
                "deny" -> {
                    user?.let {
                        getActivitiesPublisher(it, false)
                    }
                }
                else -> {
                    user?.let {
                        getActivitiesPublisher(it, true).apply {
                            addAll(getActivitiesPublisher(it, null))
                            addAll(getActivitiesPublisher(it, false))
                        }
                    }
                }
            } ?: listOf<Activity4PublisherVo>()
            return ResponseEntity.ok(JsonBody(0, "成功", list))
        }
    }

    private fun getActivitiesPublisher(user: User, pageable: Pageable): Page<Activity4PublisherVo> {
        val activities = activityService.findActivityByPublisher(user, pageable)
        return PageImpl<Activity4PublisherVo>(activities.content.map {
            val num = signUpActivityService.getUserForm(it.id, true).size
            Activity4PublisherVo(ActivityInfoVo(it, num), it.checked)
        }, PageRequest.of(activities.number, activities.size), activities.totalElements)
    }

    private fun getActivitiesPublisher(user: User, checked: Boolean?, pageable: Pageable): Page<Activity4PublisherVo> {
        val activities = activityService.findActivityByPublisher(user, checked, pageable)

        return PageImpl<Activity4PublisherVo>(activities.content.map {
            val num = signUpActivityService.getUserForm(it.id, true).size
            Activity4PublisherVo(ActivityInfoVo(it, num), checked)
        }, PageRequest.of(activities.number, activities.size), activities.totalElements)
    }

    private fun getActivitiesPublisher(user: User, checked: Boolean?): MutableList<Activity4PublisherVo> = activityService.findActivityByPublisher(user, checked).map {
        val num = signUpActivityService.getUserForm(it.id, true).size
        Activity4PublisherVo(ActivityInfoVo(it, num), checked)
    }.toMutableList()

    ///上传用户头像图片
    @PostMapping("/users/{id}/avatar")
    fun uploadAvatar(@PathVariable("id") uId: Int, @RequestParam("file", required = false) file: MultipartFile?): ResponseEntity<JsonBody<*>> {
        file?.let {
            return ResponseEntity.ok(JsonBody(0, "成功", pictureService.saveAvatar(it, uId)))

        }
        return ResponseEntity.badRequest().body(JsonBody(-1, "失败", Any()))

    }

    /**
     * 登录
     */
    @PostMapping("/login")
    fun login(@RequestBody loginVo: LoginVo): ResponseEntity<*> {
        var userId = -1
        var token: String? = null

        if (loginVo.account != null && loginVo.password != null) {
            userService.login(loginVo.account!!, rsaService.decoder(loginVo.password!!)).apply {
                token = first
                userId = second ?: return ResponseEntity.ok(JsonBody(-1, "账号或密码错误", LoginResultVo(-1, null)))

            }
        } else if (loginVo.wxcode != null) {
            userService.login(loginVo.wxcode!!).apply {
                token = first
                userId = second
                        ?: return ResponseEntity.ok(JsonBody(-2, "请先注册并绑定微信，或者稍后再试", LoginResultVo(-1, null)))

            }
        } else {
            return ResponseEntity.badRequest().body(JsonBody(-3, "必须填写账户密码或者wxcode", Any()))

        }

        return token?.let {
            ResponseEntity.ok(JsonBody(0, "成功", LoginResultVo(userId, it)))
        } ?: ResponseEntity.ok(JsonBody(-1, "账号或密码错误", LoginResultVo(-1, null)))
    }

    //获取发布者发布的所有活动的申请信息
    @GetMapping("/users/{id}/message")
    fun getMessages(@PathVariable("id") pId: Int, @RequestParam("state", required = false, defaultValue = "default") state: String): ResponseEntity<*> {
        val publisher = userService.getUser(pId)
        publisher?.let {
            when (state) {
                "passing" -> {
                    val result = getMessageList(it, null)
                    return ResponseEntity.ok(JsonBody(0, "成功", result))
                }
                "passed" -> {
                    val result = getMessageList(it, true)
                    return ResponseEntity.ok(JsonBody(0, "成功", result))
                }
                "deny" -> {
                    val result = getMessageList(it, false)
                    return ResponseEntity.ok(JsonBody(0, "成功", result))
                }
                else -> {
                    val result = getMessageList(it, null).toMutableList().apply {
                        addAll(getMessageList(it, true))
                        addAll(getMessageList(it, false))
                    }
                    return ResponseEntity.ok(JsonBody(0, "成功", result))
                }

            }
        } ?: return ResponseEntity.badRequest().body(JsonBody(-1, "未找到发布者(id=${pId})", Any()))
    }

    private fun getMessageList(publisher: User, passed: Boolean?): List<MessageVo> {
        val activities = activityService.findActivityByPublisher(publisher, true)
        var result: MutableList<MessageVo> = arrayListOf()
        for (a in activities) {
            val joiners = signUpActivityService.getUserForm(a.id, passed)
            for (u in joiners) {
                val userVo = UserVo().apply { setInfo(u) }
                val activityInfoVo = ActivityInfoVo(a, signUpActivityService.getUserForm(a.id, true).size)
                val item = MessageVo(userVo, activityInfoVo)
                System.err.println(userVo)
                System.err.println(activityInfoVo)
                System.err.println(item)
                result.add(item)
            }
        }
        return result
    }

    //发布者审批是否同意参与活动的申请。
    @PutMapping("/users/{userId}/pass/{activityId}")
    fun passJoiners(@PathVariable("userId") userId: Int, @PathVariable("activityId") activityId: Int, @RequestParam("state") state: Boolean): ResponseEntity<*> {
        signUpActivityService.pass(userId, activityId, state)
        return ResponseEntity.ok(JsonBody(0, "成功", Any()))
    }


    //用户签到
    @PutMapping("/users/{userId}/sign/{activityId}")
    fun signIn(@PathVariable("userId") userId: Int, @PathVariable("activityId") activityId: Int): ResponseEntity<*> {
        signUpActivityService.signIn(userId, activityId)
        return ResponseEntity.ok(JsonBody(0, "成功", Any()))
    }

    //获取某用户签到的活动
    @GetMapping("/users/{id}/sign")
    fun getSignActivities(@PathVariable("id") uId: Int, @RequestParam("state") state: Boolean): ResponseEntity<*> {
        val result = signUpActivityService.getSignActivities(uId, state).map {
            ActivityInfoVo(it, signUpActivityService.getUserForm(it.id).size)
        }
        return ResponseEntity.ok(JsonBody(0, "成功", result))
    }

    //绑定某用户的微信账号
    @PutMapping("/users/{id}/bind")
    fun bindAccount(@PathVariable("id") id: Int, @RequestParam("code") code: String): ResponseEntity<*> {
        val user = userService.getUser(id)
        user?.let {
            val result = userService.bindWXAccount(user, code)
            return ResponseEntity.ok(JsonBody(result.second, result.first, Any()))
        } ?: return ResponseEntity.badRequest().body(JsonBody(-1, "未找到id=${id}的用户", Any()))
    }

}